package com.ruoyi.client.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpStatus;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.client.mapper.OrderMapper;
import com.ruoyi.client.service.OrderServiceImpl;
import com.ruoyi.client.yu.common.common.enums.OrderStatus;
import com.ruoyi.client.yu.common.common.util.PayjsUtil;
import com.ruoyi.client.yu.common.entity.app.OrderInfo;
import com.ruoyi.client.yu.common.entity.app.form.CreateOrderForm;
import com.ruoyi.client.yu.common.entity.app.vo.HistoryOrderVO;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Anonymous  //跳过Ruoyi框架认证。使用Satoken框架了
@Api(tags = "订单服务")
@RestController("clientOrderController")
@Slf4j
@RequestMapping("/order")
public class OrderController {

    @Resource
    private OrderServiceImpl orderService;
    @Resource
    private OrderMapper orderMapper;


    @ApiModelProperty("下订单")
    @PostMapping("/create")
    public R<String> createOrder(@RequestBody CreateOrderForm orderParams) {
        return orderService.createOrder(orderParams);
    }

    @ApiOperation("获取payJS支付小程序支付需要的支付参数信息")
    @GetMapping("/payMP/{orderNo}")
    public R payJSMP(@PathVariable String orderNo) {
        // 模拟支付
        OrderInfo orderInfo = orderMapper.selectById(orderNo);
        orderInfo.setOrderStatus(OrderStatus.ENUM_on_making.value);
        orderMapper.updateById(orderInfo);
        return R.ok();
    }

    // h5收银台方式
    @GetMapping("/payCashier/{orderNo}")
    public R<String> cashier(@PathVariable String orderNo, HttpServletRequest request) {
        // 模拟支付
        OrderInfo orderInfo = orderMapper.selectById(orderNo);
        orderInfo.setOrderStatus(OrderStatus.ENUM_on_making.value);
        orderMapper.updateById(orderInfo);
        return R.ok();
    }

    // TODO 小程序支付成功后马上修改订单的标志
    @ApiOperation("完成支付，并设置payjs的orderid")
    @PutMapping("/finishWeixinPay")
    public R finishWeixinPay(@RequestBody Map<String, String> data) {
        OrderInfo orderInfo = orderMapper.selectById(data.get("outTradeNo"));
        orderInfo.setPayjsOrderId(data.get("payjsOrderId"));
        if (data.get("success").equals("true"))
            orderInfo.setOrderStatus(OrderStatus.ENUM_on_making.value);
        return R.ok(orderMapper.updateById(orderInfo));
    }

    @ApiOperation(value = "接收支付返回的消息")
    @PostMapping(value = "/pay/notify")
    @Transactional
    public R parseOrderNotifyResult(HttpServletRequest req, HttpServletResponse response) {
        Map<String, String> notifyData = new HashMap<>();
        notifyData.put("return_code", req.getParameter("return_code"));
        notifyData.put("total_fee", req.getParameter("total_fee"));
        notifyData.put("out_trade_no", req.getParameter("out_trade_no")); // 自己系统里的订单号
        notifyData.put("payjs_order_id", req.getParameter("payjs_order_id"));
        notifyData.put("transaction_id", req.getParameter("transaction_id")); // 微信用户手机显示订单号
        notifyData.put("time_end", req.getParameter("time_end"));
        notifyData.put("openid", req.getParameter("openid"));
        notifyData.put("mchid", req.getParameter("mchid"));
        if (!StringUtils.isEmpty(req.getParameter("attach")))
            notifyData.put("attach", req.getParameter("attach")); // 用户自定义的数据原样返回
        if (!StringUtils.isEmpty(req.getParameter("type")))
            notifyData.put("type", req.getParameter("type"));  // 支付宝交易传值：alipay ，微信支付无需此字段
        if (PayjsUtil.sign(notifyData).equals(req.getParameter("sign"))) {
            String orderNo = req.getParameter(("out_trade_no"));
            if (!"1".equals(req.getParameter(("return_code")))) {
                response.setStatus(HttpStatus.HTTP_BAD_REQUEST);
                return R.fail("订单" + orderNo + "处理失败, 未支付!");
            }

            // TODO 这里的回调会在小程序支付成功几秒后左右，插入微信交易号和支付金额
            // 官方: 自己处理订单的业务逻辑，需要判断订单是否已经支付过，否则可能会重复调用,
            OrderInfo info = new OrderInfo();
            info.setOrderNo(orderNo);
            info.setOrderStatus(OrderStatus.ENUM_on_making.value);
            info.setPayjsOrderId(req.getParameter("payjs_order_id"));
            info.setWxPayTransactionId(req.getParameter("transaction_id"));
            info.setPayPrice(Integer.parseInt(req.getParameter("total_fee")));
            try {
                info.setPayTime(DateUtil.parseTime(req.getParameter("time_end")));
            } catch (Exception e) {
                log.warn("fail to parse time_end");
            }
            orderMapper.updateById(info);
            return R.ok();
        }
        response.setStatus(HttpStatus.HTTP_BAD_REQUEST);
        return R.fail("验签失败");
    }

    @ApiOperation("取消订单")
    @DeleteMapping("/cancel/{orderNo}")
    public R<String> cancelOrder(@ApiParam("订单号") @PathVariable String orderNo) {
        return orderService.cancelOrder(orderNo);
    }

    @ApiOperation("确认收货")
    @PutMapping("/confirmReceive/{orderNo}")
    public R confirm(@ApiParam("订单号") @PathVariable String orderNo) {
        return R.ok(orderService.finishedOrder(orderNo));
    }

    @ApiOperation("分页获取历史订单")
    @GetMapping("/history/page/{pageNo}/{pageSize}")
    public R<Page<HistoryOrderVO>> getHistoryOrderByPage(@PathVariable Integer pageNo,
                                                         @PathVariable Integer pageSize) {
        return R.ok(orderService.getHistoryOrderByPage(pageNo, pageSize));
    }

    @ApiOperation("订单详情信息")
    @GetMapping("/detail/{orderNo}")
    public R<OrderInfo> getOrderDetail(@PathVariable String orderNo) {
        return R.ok(orderService.getOrderDetail(orderNo));
    }

    @ApiOperation("获取正在处理的订单列表")
    @GetMapping("/notCompleted")
    public R<List<OrderInfo>> getHandlingOrders() {
        return R.ok(orderService.getHandlingOrders());
    }

}
